package cube

import (
	"database/sql"
	"fmt"
	"shqsoft.cn/pasnj/base"
	"shqsoft.cn/pasnj/bi/database"
	"strconv"
	"time"

	"github.com/go-redis/redis"
	log "github.com/sirupsen/logrus"
)

//Division 员工分配
type Division struct {
	redisCli *redis.Client
	hkey     string
	lkey     string
	skey2    string
	lkey2    string
	keyCol   string
	diviCol  string
}

//NewDivision 员工分配
func NewDivision(diviType string) (div *Division, err error) {
	var hkey, lkey, skey2, lkey2 string
	keyCol := "ACID"
	diviCol := "DSVL"
	switch diviType {
	case "comp_acco_divi":
		hkey = "dc:h:"
		lkey = "dc:l:"
		skey2 = "dc2:h:"
		lkey2 = "dc2:l:"
	case "indi_acco_divi":
		hkey = "dis:h:"
		lkey = "dis:l:"
		skey2 = "dis2:h:"
		lkey2 = "dis2:l:"
	case "indi_fana_divi":
		hkey = "dif:h:"
		lkey = "dif:l:"
		skey2 = "dis2:h:"
		lkey2 = "dis2:l:"
	case "indi_loan_divi":
		hkey = "dil:h:"
		lkey = "dil:l:"
		skey2 = "dil2:h:"
		lkey2 = "dil2:l:"
	case "indi_clie_divi":
		hkey = "dic:h:"
		lkey = "dic:l:"
		skey2 = "dic2:h:"
		lkey2 = "dic2:l:"
		keyCol = "CUID"
		diviCol = "BSVL"
	default:
		return nil, fmt.Errorf("指定的员工分配类型%s不存在！", diviType)
	}
	div = &Division{
		redisCli: base.RedisClients[0],
		hkey:     hkey,
		lkey:     lkey,
		skey2:    skey2,
		lkey2:    lkey2,
		keyCol:   keyCol,
		diviCol:  diviCol,
	}
	return
}
func (d *Division) getTableName() string {
	pref := string(([]byte(d.hkey))[:3])
	var tName string
	switch pref {
	case "dc:":
		tName = "divi_comp_acco"
	case "dis":
		tName = "divi_indi_acco"
	case "dif":
		tName = "divi_indi_fana"
	case "dil":
		tName = "divi_indi_loan"
	case "dic":
		tName = "divi_indi_clie"
	}
	return tName
}
func (d *Division) build(date string) error {
	month := string(([]byte(date))[:6])
	err := d.delete(month)
	if err != nil {
		return err
	}
	tName := d.getTableName()
	log.Infof("开始构建分户表:%s,月份:%s....", tName, month)
	dl := database.DefaultDataLoader
	rows, err := dl.LoadDataByProc(tName, date)
	if err != nil {
		return err
	}
	defer rows.Close()
	cols, err := base.GetColumns(rows)
	if err != nil {
		return err
	}
	clen := len(cols)
	values := make([]sql.NullString, clen)
	scanArgs := make([]interface{}, clen)
	for i := 0; i < clen; i++ {
		scanArgs[i] = &values[i]
	}
	for rows.Next() {
		err := rows.Scan(scanArgs...)
		if err != nil {
			return err
		}
		if err := d.addData(month, base.ToMap(cols, values)); err != nil {
			return err
		}
	}
	log.Infof("构建分户表:%s,月份:%s完成", tName, month)
	return nil
}
func (d *Division) addData(month string, data map[string]interface{}) error {
	tName := d.getTableName()
	key, ok := data[d.keyCol]
	if !ok {
		return fmt.Errorf("给定的表%s中不存在字段%s", tName, d.keyCol)
	}
	emid, ok := data["EMID"]
	if !ok {
		return fmt.Errorf("给定的表%s中不存在字段EMID", tName)
	}
	keyStr := base.ToString(key)
	field := base.ToString(emid)
	dsvl := data[d.diviCol]
	hkey := d.hkey + month + ":" + keyStr
	find := d.redisCli.Exists(hkey).Val()
	if find == 0 {
		if err := d.redisCli.RPush(d.lkey+month, keyStr).Err(); err != nil {
			return err
		}
	}
	if err := d.redisCli.HSet(hkey, field, dsvl).Err(); err != nil {
		return err
	}
	skey2 := d.skey2 + month + ":" + field
	find = d.redisCli.Exists(skey2).Val()
	if find == 0 {
		if err := d.redisCli.RPush(d.lkey2+month, field).Err(); err != nil {
			return err
		}
	}
	if err := d.redisCli.SAdd(skey2, keyStr).Err(); err != nil {
		return err
	}
	return nil
}

//GetDivision 获取业务认定关系
func (d *Division) GetDivision(month string, key string) (map[string]float64, error) {
	divi, err := d.redisCli.HGetAll(d.hkey + month + ":" + key).Result()
	if err != nil {
		return nil, err
	}
	if len(divi) == 0 {
		date, _ := time.Parse("20060102", month+"01")
		predate := date.AddDate(0, 0, -1)
		divi, err = d.redisCli.HGetAll(d.hkey + predate.Format("200601") + ":" + key).Result()
	}
	if err != nil {
		return nil, err
	}
	retDivi := make(map[string]float64)
	var val float64
	for k, v := range divi {
		val, err = strconv.ParseFloat(v, 64)
		if err != nil {
			return nil, fmt.Errorf("占比值%s不是数字！", v)
		}
		retDivi[k] = val
	}
	if len(retDivi) == 0 {
		retDivi["0"] = 1
	}
	return retDivi, nil
}

//GetRelation 获取员工的认定关系
func (d *Division) GetRelation(month string, emid string) ([]string, error) {
	return d.redisCli.SMembers(d.skey2 + month + ":" + emid).Result()
}
func (d *Division) getRelationKey(month string, emid string) string {
	return d.skey2 + month + ":" + emid
}

//Delete 清除Index缓存
func (d *Division) delete(month string) error {
	if err := deleteByList(d.redisCli, d.hkey+month+":", d.lkey+month); err != nil {
		return err
	}
	if err := deleteByList(d.redisCli, d.skey2+month+":", d.lkey2+month); err != nil {
		return err
	}
	if err := d.redisCli.Del(d.lkey + month).Err(); err != nil {
		return err
	}
	if err := d.redisCli.Del(d.lkey2 + month).Err(); err != nil {
		return err
	}
	return nil
}
